﻿using AJWPFAdmin.Core.Logger;
using AJWPFAdmin.Core.Utils;
using DocumentFormat.OpenXml.Office2013.Excel;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace AJWPFAdmin.Core.Models
{
    /// <summary>
    /// 车辆识别配置
    /// </summary>
    public class CarIdentificationConfig
    {
        /// <summary>
        /// 图片存储位置类型
        /// </summary>
        public enum StoreType
        {
            本地,
            网络
        }
        /// <summary>
        /// 图片存放路径
        /// </summary>
        public string ImageSavePath { get; set; }

        /// <summary>
        /// 图片存储位置类型
        /// </summary>
        public StoreType Type { get; set; }

        /// <summary>
        /// 推送地址
        /// </summary>
        public string PushUrl { get; set; }

        public static string GetDefaultSavePath()
        {
            return Path.Combine(Directory.GetCurrentDirectory(), "CarNoImages");
        }

        public string CompleteFileUrl(string carNo, string fileName)
        {
            return Type == StoreType.本地
                ? Path.Combine(ImageSavePath, carNo, Path.GetFileName(fileName))
                : fileName;
        }

        /// <summary>
        /// 上传本地文件到web服务
        /// </summary>
        /// <param name="localFile"></param>
        /// <returns></returns>
        public async Task<string> UploadToWebServiceAsync(string localFile,
            Dictionary<string, string> @params,
            Action<string> logHandler = null)
        {
            try
            {
                using var client = new HttpClient();
                var fs = new FileStream(localFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);

                var content = new MultipartFormDataContent($"----Boundary{DateTime.Now.Ticks.ToString("x")}")
                    {
                        { new StreamContent(fs), "file" , HttpUtility.UrlEncode(Path.GetFileName(localFile)) },
                        
                    };

                var query = string.Empty;

                if (@params?.Count > 0)
                {
                    //foreach (var item in @params)
                    //{
                    //    //content.Add(new StringContent(item.Value), item.Key);
                    //}
                    query = $"?{string.Join("&", @params.Select(p => $"{p.Key}={HttpUtility.UrlEncode(p.Value)}"))}";
                }

                var res = await client.PostAsync($"http://{ImageSavePath}/platform/common/upload{query}", content);

                if (res.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var json = await res.Content.ReadAsStringAsync();

                    var result = Utils.CommonUtil.TryGetJSONObject<ProcessResult>(json) ?? new ProcessResult
                    {
                        Success = false,
                        Message = "解析失败"
                    };

                    if (!result.Success)
                    {
                        logHandler?.Invoke($"上传至web服务失败:{result.Message}\r\n地址:{ImageSavePath}\r\n本地文件:{localFile}");
                    }

                    localFile = (result.Data as JArray).FirstOrDefault()["url"].ToString();
                }
                else
                {
                    logHandler?.Invoke($"上传至web服务失败:{res.StatusCode}\r\n地址:{ImageSavePath}\r\n本地文件:{localFile}");
                    localFile = string.Empty;
                }
            }
            catch (Exception e)
            {
                logHandler?.Invoke($"上传至web服务异常:{e.Message}\r\n地址:{ImageSavePath}\r\n本地文件:{localFile}");
                localFile = string.Empty;
            }
            return localFile;
        }

        public (string file, bool success) UploadToWebService(string localFile,
            Dictionary<string, string> @params,
            Action<string> logHandler = null)
        {
            var success = false;
            try
            {
                using var client = new HttpClient();
                var fs = new FileStream(localFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);

                var content = new MultipartFormDataContent($"----Boundary{DateTime.Now.Ticks.ToString("x")}")
                    {
                        { new StreamContent(fs), "file" , HttpUtility.UrlEncode(Path.GetFileName(localFile)) },
                        
                    };

                var query = string.Empty;

                if (@params?.Count > 0)
                {
                    query = $"?{string.Join("&", @params.Select(p => $"{p.Key}={HttpUtility.UrlEncode(p.Value)}"))}";
                }

                var resTask = client.PostAsync($"http://{ImageSavePath}:5000/platform/common/upload{query}", content);
                resTask.Wait();
                var res = resTask.Result;
                if (res.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var jsonTask = res.Content.ReadAsStringAsync();

                    jsonTask.Wait();

                    var json = jsonTask.Result;

                    var result = Utils.CommonUtil.TryGetJSONObject<ProcessResult>(json) ?? new ProcessResult
                    {
                        Success = false,
                        Message = "解析失败"
                    };
                    success = result.Success;

                    if (!result.Success)
                    {
                        logHandler?.Invoke($"上传至web服务失败:{result.Message}\r\n地址:{ImageSavePath}\r\n本地文件:{localFile}");
                    }
                    else
                    {
                        localFile = (result.Data as JArray).FirstOrDefault()["url"].ToString();
                    }
                }
                else
                {
                    logHandler?.Invoke($"上传至web服务失败:{res.StatusCode}\r\n地址:{ImageSavePath}\r\n本地文件:{localFile}");
                }
            }
            catch (Exception e)
            {
                logHandler?.Invoke($"上传至web服务异常:{e.Message}\r\n地址:{ImageSavePath}\r\n本地文件:{localFile}");
                success = false;
            }
            return (localFile, success);
        }

        public ProcessResult Push(IEnumerable<string> localFiles,
            Dictionary<string, string> @params,
            Action<string> logHandler = null)
        {
            var result = new ProcessResult();
            try
            {
                if ((localFiles?.Count()).GetValueOrDefault() == 0)
                {
                    result.SetSuccess();
                    logHandler?.Invoke($"没有任何图片文件需要推送");
                    return result;
                }

                var content = new MultipartFormDataContent($"----Boundary{DateTime.Now.Ticks.ToString("x")}");

                var fileStreams = new List<Stream>();

                foreach (var file in localFiles)
                {
                    var stream = CommonUtil.GetImageStreamFromLocalOrHttp(file, out _);
                    if (stream == null)
                    {
                        continue;
                    }

                    fileStreams.Add(stream);

                    content.Add(new StreamContent(stream), "file", HttpUtility.UrlEncode(Path.GetFileName(file)));
                }

                if (fileStreams.Count == 0)
                {
                    result.SetSuccess();
                    logHandler?.Invoke($"未找到任何图片文件");
                    return result;
                }

                var query = string.Empty;

                if (@params?.Count > 0)
                {
                    foreach (var param in @params)
                    {
                        content.Add(new StringContent(param.Value, Encoding.UTF8), param.Key);
                    }
                }

                using var client = new HttpClient();

                var resTask = client.PostAsync(PushUrl, content);
                resTask.Wait();

                foreach (var stream in fileStreams)
                {
                    stream.Dispose();
                }

                var res = resTask.Result;
                if (res.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    result.SetSuccess();
                }
                else
                {
                    result.SetError("上传失败");
                    logHandler?.Invoke($"推送图片失败:{res.StatusCode}\r\n地址:{PushUrl}");
                }
            }
            catch (Exception e)
            {
                logHandler?.Invoke($"推送图片异常:{e.Message}\r\n地址:{PushUrl}");
                result.SetError(e.Message);
            }

            return result;
        }
    }
}
